/**
 * https://leetcode.cn/problems/find-all-anagrams-in-a-string/?envType=study-plan-v2&envId=top-100-liked
 * 
 * 给定两个字符串 s 和 p，找到 s 中所有 p 的 异位词 的子串，返回这些子串的起始索引。不考虑答案输出的顺序。

异位词 指由相同字母重排列形成的字符串（包括相同的字符串）。

 

示例 1:

输入: s = "cbaebabacd", p = "abc"
输出: [0,6]
解释:
起始索引等于 0 的子串是 "cba", 它是 "abc" 的异位词。
起始索引等于 6 的子串是 "bac", 它是 "abc" 的异位词。
 示例 2:

输入: s = "abab", p = "ab"
输出: [0,1,2]
 * @param {string} s
 * @param {string} p
 * @return {number[]}
 */
var findAnagrams = function (s, p) {
  const res = [];
  const pLength = p.length;
  const sLength = s.length;

  // 处理特殊情况
  if (pLength > sLength) {
    return res;
  }

  // 创建计数器
  const pCounter = new Array(26).fill(0);
  const sCounter = new Array(26).fill(0);

  // 初始化 p 和 s 的第一个窗口的计数器
  for (let i = 0; i < pLength; i++) {
    pCounter[p.charCodeAt(i) - "a".charCodeAt(0)]++;
    sCounter[s.charCodeAt(i) - "a".charCodeAt(0)]++;
  }

  // 滑动窗口
  for (let i = 0; i <= sLength - pLength; i++) {
    if (pCounter.every((count, index) => count === sCounter[index])) {
      res.push(i);
    }
    // 更新滑动窗口
    if (i + pLength < sLength) {
      sCounter[s.charCodeAt(i) - "a".charCodeAt(0)]--;
      sCounter[s.charCodeAt(i + pLength) - "a".charCodeAt(0)]++;
    }
  }

  return res;
};
const s = "abab",
  p = "ab";
console.log(findAnagrams(s, p));
